/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wordplat.quickstart.slider;

import com.wordplat.ikvstockchart.InteractiveKLineLayout;
import com.wordplat.ikvstockchart.KLineHandler;
import com.wordplat.ikvstockchart.entry.Entry;
import com.wordplat.ikvstockchart.entry.EntrySet;
import com.wordplat.ikvstockchart.entry.SizeColor;
import com.wordplat.ikvstockchart.render.KLineRender;
import com.wordplat.quickstart.ResourceTable;
import com.wordplat.quickstart.bean.KLineBean;
import com.wordplat.quickstart.mvp.LoadingViewListener;
import com.wordplat.quickstart.mvp.StockPresenter;
import com.wordplat.quickstart.utils.ToastViewDialog;
import com.wordplat.quickstart.wight.PullLayout.pulllistview.HeadDefaultComponent;
import com.wordplat.quickstart.wight.PullLayout.pulllistview.IRefresh;
import com.wordplat.quickstart.wight.PullLayout.pulllistview.RefreshComponent;

import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.*;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.multimodalinput.event.TouchEvent;

import java.util.List;

import static ohos.agp.components.Component.VISIBLE;

/**
 * PagerProvider
 *
 * @since 2021-04-22
 */
public class PagerProvider extends PageSliderProvider {
    /**
     * 中信证券
     */
    private static final String STOCK_CODE = "600030";
    private static final int REQUEST_STOCK_FIRST = 1;
    private static final int REQUEST_STOCK_PREV = 2;
    private static final int REQUEST_STOCK_NEXT = 3;
    private static RefreshComponent refreshComponent;

    private final Context mContext;
    private InteractiveKLineLayout kLineLayout = null;
    private Text MA_Text = null;
    private Text StockIndex_Text = null;
    private Text Volume_Text = null;
    private Image Left_Loading_Image;
    private Image Right_Loading_Image;

    private RadioContainer But_Group;
    private RadioButton MACD_But;
    private RadioButton RSI_But;
    private RadioButton KDJ_But;
    private RadioButton BOLL_But;

    private static final int loadStartPos = 5500;
    private static final int loadEndPos = 6000;
    private static final int loadCount = 100;

    private final StockPresenter.KLineType kLineType;
    private final EntrySet entrySet = new EntrySet();
    private final StockPresenter presenter = new StockPresenter();

    private AnimatorProperty mAnimator;

    private final LoadingViewListener viewListener = new LoadingViewListener() {
        @Override
        public void onStartRequest(int requestCode) {
            switch (requestCode) {
                case REQUEST_STOCK_PREV:
                    Left_Loading_Image.setVisibility(VISIBLE);
                    mAnimator = Left_Loading_Image.createAnimatorProperty();
                    mAnimator.setDuration(1500).rotate(360).setLoopedCount(AnimatorProperty.INFINITE)
                            .setTarget(Left_Loading_Image).start();
                    break;

                case REQUEST_STOCK_NEXT:
                    Right_Loading_Image.setVisibility(VISIBLE);
                    mAnimator = Right_Loading_Image.createAnimatorProperty();
                    mAnimator.setDuration(1500).rotate(360).setLoopedCount(AnimatorProperty.INFINITE)
                            .setTarget(Right_Loading_Image).start();
                    break;
            }
        }

        @Override
        public void onFinishRequest(int requestCode) {
            switch (requestCode) {
                case REQUEST_STOCK_PREV:
                    TaskDispatcher globalTaskDispatcher = mContext.getMainTaskDispatcher();
                    Runnable runnable = new Runnable() {
                        @Override
                        public void run() {
                            Left_Loading_Image.setVisibility(Component.HIDE);
                            ToastViewDialog.toast(mContext, "已经到达最左边了");
                        }
                    };
                    globalTaskDispatcher.delayDispatch(runnable, 1500);
                    break;
                case REQUEST_STOCK_NEXT:
                    TaskDispatcher globalTaskDispatcher2 = mContext.getMainTaskDispatcher();
                    Runnable runnable2 = new Runnable() {
                        @Override
                        public void run() {
                            Right_Loading_Image.setVisibility(Component.HIDE);
                            ToastViewDialog.toast(mContext, "已经到达最右边了");
                        }
                    };
                    globalTaskDispatcher2.delayDispatch(runnable2, 1500);
                    break;
            }
        }

        @Override
        public void onSuccess(int requestCode) {
            List<KLineBean> response = presenter.getkLineList();

            switch (requestCode) {
                case REQUEST_STOCK_FIRST:
                    for (KLineBean kLineBean : response) {
                        entrySet.addEntry(new Entry(kLineBean.getOpen(),
                                kLineBean.getHigh(),
                                kLineBean.getLow(),
                                kLineBean.getClose(),
                                kLineBean.getVolume(),
                                kLineBean.getDate()));
                    }
                    entrySet.computeStockIndex();
                    kLineLayout.getKLineView().setEntrySet(entrySet);
                    break;

                case REQUEST_STOCK_PREV:
                    for (int i = response.size() - 1; i >= 0; i--) {
                        KLineBean kLineBean = response.get(i);
                        entrySet.insertFirst(new Entry(kLineBean.getOpen(),
                                kLineBean.getHigh(),
                                kLineBean.getLow(),
                                kLineBean.getClose(),
                                kLineBean.getVolume(),
                                kLineBean.getDate()));
                    }
                    entrySet.computeStockIndex();
                    kLineLayout.getKLineView().refreshComplete(response.size() > 0);
                    break;

                case REQUEST_STOCK_NEXT:
                    for (KLineBean kLineBean : response) {
                        entrySet.addEntry(new Entry(kLineBean.getOpen(),
                                kLineBean.getHigh(),
                                kLineBean.getLow(),
                                kLineBean.getClose(),
                                kLineBean.getVolume(),
                                kLineBean.getDate()));
                    }
                    entrySet.computeStockIndex();
                    kLineLayout.getKLineView().refreshComplete(response.size() > 0);
                    break;
            }
        }

        @Override
        public void onResultEmpty(int requestCode) {
            switch (requestCode) {
                case REQUEST_STOCK_FIRST:
                    break;

                case REQUEST_STOCK_PREV:
                    kLineLayout.getKLineView().refreshComplete(false);

                    break;

                case REQUEST_STOCK_NEXT:
                    kLineLayout.getKLineView().refreshComplete(false);

                    break;
            }
        }

        @Override
        public void onNetworkTimeOutError(int requestCode) {
            super.onNetworkTimeOutError(requestCode);

            switch (requestCode) {
                case REQUEST_STOCK_FIRST:
                    entrySet.setLoadingStatus(false);
                    break;
            }
        }

        @Override
        public void onNoNetworkError(int requestCode) {
            super.onNoNetworkError(requestCode);

            switch (requestCode) {
                case REQUEST_STOCK_FIRST:
                    entrySet.setLoadingStatus(false);
                    break;
            }
        }
    };

    /**
     * PagerProvider
     *
     * @param context
     * @param type
     */
    public PagerProvider(Context context, StockPresenter.KLineType type) {
        this.mContext = context;
        this.kLineType = type;
    }

    @Override
    public int getCount() {
        return 1;
    }

    @Override
    public Object createPageInContainer(ComponentContainer componentContainer, int i) {
        DirectionalLayout layout = (DirectionalLayout) LayoutScatter.getInstance(mContext).parse(
                ResourceTable.Layout_slider_kline, null, false);
        initViews(layout);
        initUI();
        componentContainer.addComponent(layout);
        setRefresh();
        presenter.attachView(viewListener);
        presenter.loadFirst(REQUEST_STOCK_FIRST, STOCK_CODE, kLineType);
        return layout;
    }

    private void setRefresh() {
        refreshComponent.setKLineView(kLineLayout.getKLineView());
        /**
         * 设置头部刷新样式,可自定义样式
         */
        HeadDefaultComponent headDefaultComponent = new HeadDefaultComponent(refreshComponent.getContext());
        /**
         * 添加样式到头部
         */
        refreshComponent.setHeadComponent(headDefaultComponent);
        /**
         * 设置刷新回调
         */
        refreshComponent.setRefreshListener(new IRefresh.RefreshListener() {
            @Override
            public void onRefresh() {
                new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
                    @Override
                    public void run() {
                        /**
                         * 数据更新完  结束掉刷新
                         */
                        refreshComponent.refreshFinish();
                    }
                }, 2000);
            }

            @Override
            public boolean enableRefresh() {
                return false;
            }
        });
    }

    private void initUI() {
        kLineLayout.setClick(But_Group, MACD_But, RSI_But, KDJ_But, BOLL_But);
        kLineLayout.getKLineView().isEmpty(true);
        kLineLayout.setKLineHandler(new KLineHandler() {
            @Override
            public void onHighlight(Entry entry, int entryIndex, float x, float y) {
                String maString = null;
                String volumeString = null;
                String str = null;
                maString = String.format(String.valueOf(mContext.getString(ResourceTable.String_ma_highlight)),
                        entry.getMa5(),
                        entry.getMa10(),
                        entry.getMa20());
                volumeString = String.format(String.valueOf(mContext.getString(ResourceTable.String_volume_highlight)),
                        entry.getVolumeMa5(),
                        entry.getVolumeMa10());
                if (kLineLayout.isShownMACD()) {
                    str = String.format(String.valueOf(mContext.getString(ResourceTable.String_macd_highlight)),
                            entry.getDiff(),
                            entry.getDea(),
                            entry.getMacd());
                } else if (kLineLayout.isShownKDJ()) {
                    str = String.format(String.valueOf(mContext.getString(ResourceTable.String_kdj_highlight)),
                            entry.getK(),
                            entry.getD(),
                            entry.getJ());
                } else if (kLineLayout.isShownRSI()) {
                    str = String.format(String.valueOf(mContext.getString(ResourceTable.String_rsi_highlight)),
                            entry.getRsi1(),
                            entry.getRsi2(),
                            entry.getRsi3());
                } else if (kLineLayout.isShownBOLL()) {
                    str = String.format(String.valueOf(mContext.getString(ResourceTable.String_boll_highlight)),
                            entry.getMb(),
                            entry.getUp(),
                            entry.getDn());
                }

                MA_Text.setText(maString);
                Volume_Text.setText(volumeString);
                StockIndex_Text.setText(str);
            }

            @Override
            public void onCancelHighlight() {
                String maString = null;
                String stockIndexString = "";
                maString = String.valueOf(mContext.getString(ResourceTable.String_ma_normal));
                if (kLineLayout.isShownMACD()) {
                    stockIndexString = String.valueOf(mContext.getString(ResourceTable.String_macd_normal));
                } else if (kLineLayout.isShownKDJ()) {
                    stockIndexString = String.valueOf(mContext.getString(ResourceTable.String_kdj_normal));
                } else if (kLineLayout.isShownRSI()) {
                    stockIndexString = String.valueOf(mContext.getString(ResourceTable.String_rsi_normal));
                } else if (kLineLayout.isShownBOLL()) {
                    stockIndexString = String.valueOf(mContext.getString(ResourceTable.String_boll_normal));
                }

                MA_Text.setText(maString);
                Volume_Text.setText("");
                StockIndex_Text.setText(stockIndexString);
            }

            @Override
            public void onLeftRefresh() {
                Left_Loading_Image.setVisibility(VISIBLE);
                mAnimator = Left_Loading_Image.createAnimatorProperty();
                mAnimator.setDuration(1500).rotate(360).setLoopedCount(AnimatorProperty.INFINITE)
                        .setTarget(Left_Loading_Image).start();
                TaskDispatcher globalTaskDispatcher = mContext.getMainTaskDispatcher();
                Runnable runnable = new Runnable() {
                    @Override

                    public void run() {
                        Left_Loading_Image.setVisibility(Component.HIDE);
                        ToastViewDialog.toast(mContext, "已经到达最左边了");
                    }
                };
                globalTaskDispatcher.delayDispatch(runnable, 1000);
            }

            @Override
            public void onRightRefresh() {
                Right_Loading_Image.setVisibility(VISIBLE);
                mAnimator = Right_Loading_Image.createAnimatorProperty();
                mAnimator.setDuration(1500).rotate(360).setLoopedCount(AnimatorProperty.INFINITE)
                        .setTarget(Right_Loading_Image).start();
                TaskDispatcher globalTaskDispatcher = mContext.getMainTaskDispatcher();
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        Right_Loading_Image.setVisibility(Component.HIDE);
                        ToastViewDialog.toast(mContext, "已经到达最右边了");
                    }
                };
                globalTaskDispatcher.delayDispatch(runnable, 1000);
            }

            @Override
            public void onSingleTap(TouchEvent e, float x, float y) {
                ToastViewDialog.toast(mContext, "single tab [" + x + ", " + y + "]");
            }

            @Override
            public void onDoubleTap(TouchEvent e, float x, float y) {
                final KLineRender kLineRender = (KLineRender) kLineLayout.getKLineView().getRender();
                if (contains(kLineRender.getKLineRect(), x, y)) {
                    kLineRender.zoomIn(x, y);
                }
            }
        });
    }

    private void initViews(DirectionalLayout layout) {
        kLineLayout = (InteractiveKLineLayout) layout.findComponentById(ResourceTable.Id_kLineLayout);
        MA_Text = (Text) layout.findComponentById(ResourceTable.Id_MA_Text);
        StockIndex_Text = (Text) layout.findComponentById(ResourceTable.Id_StockIndex_Text);
        Volume_Text = (Text) layout.findComponentById(ResourceTable.Id_Volume_Text);
        Left_Loading_Image = (Image) layout.findComponentById(ResourceTable.Id_Left_Loading_Image);
        Right_Loading_Image = (Image) layout.findComponentById(ResourceTable.Id_Right_Loading_Image);

        But_Group = (RadioContainer) layout.findComponentById(ResourceTable.Id_But_Group);
        MACD_But = (RadioButton) layout.findComponentById(ResourceTable.Id_MACD_But);
        RSI_But = (RadioButton) layout.findComponentById(ResourceTable.Id_RSI_But);
        KDJ_But = (RadioButton) layout.findComponentById(ResourceTable.Id_KDJ_But);
        BOLL_But = (RadioButton) layout.findComponentById(ResourceTable.Id_BOLL_But);
    }

    /**
     * loadData
     */
    public void loadData() {

    }

    @Override
    public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
        componentContainer.removeComponent((Component) o);
    }

    @Override
    public boolean isPageMatchToObject(Component component, Object o) {
        return true;
    }

    private boolean contains(RectFloat rectFloat, float x, float y) {
        return rectFloat.left < rectFloat.right && rectFloat.top < rectFloat.bottom
                && x >= rectFloat.left && x < rectFloat.right && y >= rectFloat.top && y < rectFloat.bottom;
    }

    /**
     * newInstance
     *
     * @param mContext
     * @param kLineType
     * @param rc
     * @return PagerProvider
     */
    public static PagerProvider newInstance(Context mContext, StockPresenter.KLineType kLineType, RefreshComponent rc) {
        PagerProvider fragment = new PagerProvider(mContext, kLineType);
        refreshComponent = rc;
        return fragment;
    }
}